using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Timers;
using System.Management;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using CodeParadise;
using System.Diagnostics;

namespace WdebugTool
{
    public partial class WdebugTool : Form
    {
        string Rev = "1.0.0";
        GroupBox[] GBx = new GroupBox[3];   //三个容器
        ComboBox[] cbx = new ComboBox[3];   //三个下拉菜单
        ComboBox cbSerial = new ComboBox();  //串口combox
        System.Timers.Timer timer;  //新建一个定时器
        Boolean timerSet = false;
        WqlEventQuery Wquery = new WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PnPEntity'");
        //static NumericUpDown[] dm = new NumericUpDown[15];  //数据设置numUpDown
        ManagementEventWatcher watcher;
        static List<NumericUpDown> dm = new List<NumericUpDown>();  //num 计数集合
        static SerialPort sPort = new SerialPort();   //初始化一个串口
        List<string> comNum = new List<string>();   //com链表
        string lastPrjName=null;
        JToken jtokenDataBuff=null;  //初始化Combox中数组数据
        public WdebugTool()
        {
            InitializeComponent();
            projectBoxUI(this);
            ProjectPlanUI(GBx[0]);  //选择方案
        }
        /************************************************************
        * #方案控件初始化
        *
        *
        *************************************************************/
        private void projectBoxUI(Control ctl)
        {
            string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), @"..\..\..\UIJson\MainGroupBox.json");
            if(!File.Exists(path)){
                MessageBox.Show("Json path file MainGroupBox is lost");
                return;
            }
            string jsonData = File.ReadAllText(path,Encoding.UTF8);
            if(jsonData==null){
                MessageBox.Show("Json file MainGroupBox.json is null");
                return;
            }
            JArray myobject = (JArray)JsonConvert.DeserializeObject(jsonData);
            //JObject myobj = JObject.Parse(jsonData);
            int idx=0,addX=5;
            int[] WH = new int[2]{0,0};
            //if(myobj["display_type"]?.ToString()=="mainGBX"){
            //    if(myobj["data"]!=null){
            //    }
            //}
            foreach(var obj in myobject)
            {
                if(obj["display_type"]?.ToString()=="mainGBX")
                {
                    foreach(var type in obj["data"])
                    {
                        if(type["control_type"]!=null){
                            GBx[idx] = new GroupBox();
                            GBx[idx].Name = type["control_name"].ToString();
                            GBx[idx].Location = new System.Drawing.Point(ctl.Location.X+addX, ctl.Location.Y+40);
                            WH = jsonSize(type["control_Size"],ctl);
                            addX += WH[0]-5;
                            GBx[idx].Size = new System.Drawing.Size(WH[0]-10,WH[1]-50);
                            GBx[idx].Text = type["control_Text"].ToString();
                            //GBx[idx].AutoSizeMode = AutoSizeMode.GrowAndShrink;
                            this.Controls.Add(GBx[idx]);
                            idx++;
                            if(idx>3){
                                MessageBox.Show("Json file GroupBox over");
                                break;
                            }
                        }
                    }
                }
            }
        }
        /*****************************************************
        * #方案类型 初始化第一个Box中的3个ComboBox控件
        *
        *
        ******************************************************/
        private void ProjectPlanUI(Control ctl){
            string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), @"..\..\..\UIJson\DebugPlanUI.json");
            if (!File.Exists(path))
            {
                MessageBox.Show("Json path file ActivePlan is lost");
                return;
            }       
            string jsonData = File.ReadAllText(path, Encoding.UTF8);
            JArray myobject = (JArray)JsonConvert.DeserializeObject(jsonData);
            int icbx=0,updir=10;
            int[] WH = new int[2]{0,0};
            foreach (var obj in myobject)
            {
                if (obj["type"]?.ToString() == "DebugPlanUI")
                {
                    jtokenDataBuff = obj["dataBuff"];
                    foreach (var type in obj["UI"])
                    {
                        switch(type["control_type"]?.ToString()){
                            case "ComboBox":
                        //if(type["control_type"]!=null){
                            //Label prjlab = new Label();
                            //LabJsonConfig(prjlab,type,ctl,ref updir);
                            ComboBox prj = new ComboBox();
                            prj.SelectedIndexChanged += new System.EventHandler(this.EventClassComboChange);
                            prj.Name = type["control_name"]?.ToString();
                            WH = jsonSize(type["control_Size"],ctl);
                            prj.Size = new System.Drawing.Size(WH[0]-5,WH[1]);
                            WH = jsonLocation(type["control_LocationShift"],ctl);
                            prj.Location = new System.Drawing.Point(WH[0], WH[1]+updir);
                            updir += WH[1];
                            //JProperty[] properties = (JObject)type["control_Items"].Properties().ToArray(); // 获取 JObject 对象的属性并转换为数组
                            //foreach(var tab in type["control_Items"]){
                            //    //tab[0].ToString();
                            //    //cbx[icbx].Items.AddRange(tab.ToArray());
                            //    cbx[icbx].Items.Add(tab["name"]);
                            //}
                            ctl.Controls.Add(prj);
                            //ctl.Controls.Add(prjlab);
                            //初始化完控件,把数据加入combox Class
                            foreach (var obj1 in jtokenDataBuff){
                                prj.Items.Add(obj1["class"]);
                            }
                            break;
                            //case "ButtonBuild":
                            //    buildBt = new Button();
                            //    buildBt.Name = type["control_name"].ToString();
                            //    WH = jsonSize(type["control_Size"],ctl);
                            //    buildBt.Size = new System.Drawing.Size(WH[0]-5,WH[1]);
                            //    buildBt.Text = type["control_Text"].ToString();
                            //    WH = jsonLocation(type["control_LocationShift"],ctl);
                            //    buildBt.Location = new System.Drawing.Point(WH[0], WH[1]+updir);
                            //    updir += WH[1];
                            //    buildBt.Click += new System.EventHandler(this.EventBuild);
                            //    ctl.Controls.Add(buildBt);
                            //break;
                            //case "pathSet":
                            //    //Label sdkpath = new Label();
                            //    //LabJsonConfig(sdkpath,type,ctl,ref updir);
                            //    //int Lp=0;
                            //    Button sdkpath = new Button();
                            //    sdkpath.Name = type["control_LabName"].ToString();
                            //    WH = jsonSize(type["control_LabSize"],ctl);
                            //    sdkpath.Size = new System.Drawing.Size(WH[0]-5,WH[1]);
                            //    sdkpath.Text = type["control_LabText"].ToString();
                            //    WH = jsonLocation(type["control_LocationShift"],ctl);
                            //    sdkpath.Location = new System.Drawing.Point(WH[0], WH[1]+updir);
                            //    updir += WH[1];
                            //    sdkpath.Click += new System.EventHandler(this.EventSetPathForDctsdk);
                            //    tbpath = new TextBox();
                            //    tbpath.Name = type["control_name"].ToString();
                            //    WH = jsonSize(type["control_Size"],ctl);
                            //    tbpath.Size = new System.Drawing.Size(WH[0]-5,WH[1]);
                            //    WH = jsonLocation(type["control_LocationShift"],ctl);
                            //    tbpath.Location = new System.Drawing.Point(WH[0], WH[1]+updir);
                            //    updir += WH[1];
                            //    ctl.Controls.Add(tbpath);
                            //    ctl.Controls.Add(sdkpath);
                            //break;
                        //}
                        }
                    }
                }
            }
            //foreach (var obj in jtokenDataBuff){
            //    cbx[0].Items.Add(obj["class"]);
            //}
        }
        /******************************************************
        *lab config read for json
        *
        *
        ******************************************************/
        private void LabJsonConfig(Label lab,JToken type,Control ctl,ref int updir){
            int[] WH = new int[2]{0,0};
            lab.Name = type["control_LabName"]?.ToString();
             //距离上一个控件间隔多少?
            WH = jsonSize(type["control_LabSize"],ctl);
            lab.Size = new System.Drawing.Size(WH[0]-5,WH[1]);
            WH = jsonLocation(type["control_LabLocationShift"],ctl);
            lab.Location = new System.Drawing.Point(WH[0], WH[1]+updir);
            updir += WH[1];
            lab.Text = type["control_LabText"].ToString();
        }
        /*****************************************************
        * #get Size for table 换算出控件大小
        *
        *
        ******************************************************/
        public static int[] jsonSize(JToken type,Control control)
        {
            int[] ret = new int[2]{0,0};
            String rg=null;
            foreach(var sz in type){
                if(sz["Wrange"]!=null){
                    rg = sz["Wrange"].ToString();
                    if(rg=="parent"){
                        ret[0] = Convert.ToInt32(sz["W%"])*control.ClientSize.Width/100;
                    }else if(rg=="value"){
                        ret[0] = Convert.ToInt32(sz["W"]);
                    }
                }
                if(sz["Hrange"]!=null){
                    rg = sz["Hrange"].ToString();
                    if(rg=="parent"){
                        ret[1] = Convert.ToInt32(sz["H%"])*control.ClientSize.Height/100;
                    }else if(rg=="value"){
                        ret[1] = Convert.ToInt32(sz["H"]);
                    }
                }
            }
            return ret; 
        }
        /*****************************************************
        * #get Location for table
        * 距离上一个控件间隔多少?
        *
        ******************************************************/
        private static int[] jsonLocation(JToken type,Control control)
        {
            int[] ret = new int[2]{0,0};
            foreach(var sz in type){
                ret[0] = Convert.ToInt32(sz["Ldir"])+control.Location.X;
                ret[1] = Convert.ToInt32(sz["Udir"])+control.Location.Y;
            }
            return ret; 
        }
        /******************************************************
         * UI Class change event
         * 不同方案选择 改变事件
         * 
        ******************************************************/
        private void EventClassComboChange(object sender,EventArgs e)
        {
            //Console.WriteLine("out" + sender.GetType().Name.ToString());
            var cbxtemp = (ComboBox)sender;
            if(lastPrjName!=cbxtemp.SelectedItem?.ToString()){
                lastPrjName = cbxtemp.SelectedItem.ToString();
                GBx[1].Controls.Clear();
                sPort.Close();
                if(timerSet==true){
                    timer.Enabled = false;
                    timer.Dispose();
                    watcher.Stop();
                }
                GBx[2].Controls.Clear();
                foreach (var obj in jtokenDataBuff){
                    if((obj["class"]?.ToString()==lastPrjName)&&(obj["func"]!=null)&&(obj["num"]?.Value<int>()>0)){
                        //int hg = GBx[1].Height;
                        //int wt = GBx[1].Width;
                        //int num = obj["num"].Value<int>();
                        //int oneH = (hg-20)/num;     //每个控件的高度
                        int initH = 20; //初始控件位置
                        dm.Clear();
                        //int dmIdx=0;
                        foreach(var fc in obj["func"]){
                            labelStyle labSt = new labelStyle();
                            switch(fc["tool"]?.ToString()){
                                case "NumericUpDown":
                                    labSt.titleStyle(fc["type"]?.ToString(),Color.FromArgb(0xb31343),8F,new Point(10,initH),GBx[1]);
                                    NumericUpDown dmt = new NumericUpDown();
                                    dmt = new NumericUpDown();
                                    dmt.Location = new Point(35+labSt.Width+labSt.Left,labSt.Top-5);
                                    dmt.Maximum = fc["max"].Value<int>();
                                    dmt.Minimum = fc["min"].Value<int>();
                                    dmt.Value = fc["now"].Value<int>();
                                    GBx[1].Controls.Add(dmt);
                                    //dmIdx++;
                                    dm.Add(dmt);
                                    initH += labSt.Height+12;
                                break;
                                case "Button":
                                    //labSt.titleStyle(fc["typeDownButton"]?.ToString(),Color.FromArgb(0xef33bd),20F,new Point(10,initH),GBx[1]);
                                    Button bt = new Button();
                                    bt.AutoSize = true;
                                    bt.Text = "点击更新参数";
                                    bt.Font = new Font("Microsoft Sans Serif", 15F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0)));  
                                    bt.BackColor = Color.LightBlue;
                                    bt.Location = new Point(50,initH);
                                    bt.Click += new System.EventHandler(this.EventButtonUartDownload);
                                    UpdateComboBox();
                                    //cbSerial.Items.Clear();
                                    //string[] ports = SerialPort.GetPortNames();
                                    //comNum.Clear();
                                    //for(int i=0;i<ports.Length;i++){
                                    //    comNum.Add(ports[i]);
                                    //    string description = GetSerialPortDescription(ports[i]);
                                    //    cbSerial.Items.Add(ports[i]+" #"+description);
                                    //    cbSerial.SelectedIndexChanged += new System.EventHandler(this.EventComComboBoxChange);
                                    //}
                                    //cbSerial.SelectedIndex = cbSerial.Items.Count>0? 0:-1;
                                    //if(cbSerial.SelectedIndex!=-1)
                                    //sPort.PortName = comNum[cbSerial.SelectedIndex];
                                    //ManagementEventWatcher 
                                    watcher = new ManagementEventWatcher(Wquery);
                                    watcher.EventArrived += new EventArrivedEventHandler(PnpEntityEventArrived);
                                    // 开始监听事件
                                    watcher.Start();
                                    cbSerial.Location = new Point(bt.Right+80,initH);
                                    GBx[1].Controls.Add(bt);
                                    GBx[1].Controls.Add(cbSerial);
                                    initH += bt.Height+12;
                                break;
                                case "saveButton":
                                    Button bt1 = new Button();
                                    bt1.AutoSize = true;
                                    bt1.Text = "保存当前参数";
                                    bt1.Font = new Font("Microsoft Sans Serif", 10F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0)));  
                                    bt1.BackColor = Color.LightCyan;
                                    bt1.Location = new Point(50,initH);
                                    bt1.Click += new System.EventHandler(this.EventButtonSaveConfig);
                                    GBx[1].Controls.Add(bt1);
                                    initH += bt1.Height+12;
                                break;
                                case "loadButton":
                                break;
                                default:
                                break;
                            }
                        }
                    }
                }
            }
        }        
        /******************************************************
         * 按键切换下载程序事件
         * 
         * 
        ******************************************************/
        private void EventButtonSaveConfig(object sender,EventArgs e)
        {
            // 创建一个SaveFileDialog实例
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //FolderBrowserDialog dir = new FolderBrowserDialog();
            // 设置对话框的标题
            saveFileDialog.Title = "选择保存文件的路径";
            // 设置默认的文件扩展名（可选）
            saveFileDialog.DefaultExt = "dctasmh";
            // 设置文件类型过滤器（可选）
            saveFileDialog.Filter = "dct头文件 (*.dctasmh)|*.dctasmh|汇编文件 (*.asm)|*.asm";
                    // 显示对话框并检查结果
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                // 获取用户选择的文件路径
                string filePath = saveFileDialog.FileName;
                string dirpath = Path.GetDirectoryName(filePath);;
                Console.WriteLine("path is "+dirpath);
                // 要保存的内容
                string content = ";//*******************************************************************\n"+
                ";//PID startup 调节舵机参数\n"+"#define cIntervalMotor "+dm[0].Value.ToString()+";//处理PID的间隔时间\n"+
                "#define cStartupPWM     "+dm[1].Value.ToString()+"    ;最小启动PWM\n"+
                "#define cmErrP  "+dm[2].Value.ToString()+" ;比例\n"+
                "#define cmErrI  "+dm[3].Value.ToString()+" ;积分\n"+
                "#define cmErrD  "+dm[4].Value.ToString()+" ;微分\n"+
                "#define cMinRunStop    "+dm[5].Value.ToString()+"    ;最小微分偏差,判断马达是否动处于静止状态,如果每次微分小于这个值表示在静止状态?\n"+
                "#define cTurnPDCount  "+dm[6].Value.ToString()+"    ;不动作计时 越大PD越长\n"+
                "#define cmMinErrToMid  "+dm[7].Value.ToString()+"   ;//最小饱和间隔\n"+
                "#define cMinRun "+dm[8].Value.ToString()+"          ;最小微分运动值,大于这个阈值表示真的有减小\n"+
                "#define cMinNegPWM  "+dm[9].Value.ToString()+"    ;//最小反向PWM\n"+
                "#define cMinPosPWM  "+dm[10].Value.ToString()+"    ;//最小正向PWM\n";
                // 使用StreamWriter将内容写入文件
                try
                {
                    using (StreamWriter writer = new StreamWriter(filePath))
                    {
                        writer.Write(content);
                    }
                    //MessageBox.Show("文件已成功保存！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //MessageBox.Show("程序生成成功");
                    DialogResult MsgBoxResult;
                    MsgBoxResult = MessageBox.Show("程序生成成功,是否开打源程序目录?", "",MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation,MessageBoxDefaultButton.Button2);
                    if (MsgBoxResult == DialogResult.Yes)//如果对话框的返回值是YES（按"Y"按钮）
                    {
                        Process.Start(new ProcessStartInfo
                        {
                            FileName = dirpath,
                            UseShellExecute = true, // 这通常是默认值，但可以明确设置以避免混淆
                            Verb = "open" // 对于文件夹，这通常是默认值，但明确设置更好
                        });
                        //Process process = new Process();//创建进程对象    
                        //ProcessStartInfo startInfo = new ProcessStartInfo(dirpath); // 括号里是(程序名,参数)
                        //process.StartInfo = startInfo;
                        //process.Start();
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show($"保存文件时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }
        }
        /******************************************************
         * 按键切换下载程序事件
         * 
         * 
        ******************************************************/
        private void EventButtonUartDownload(object sender,EventArgs e)
        {
            var bt = (Button)sender;
            if(bt.Text=="点击更新参数"){
                bt.Text = "更新中...";
                bt.BackColor=Color.LightGreen;
                if(cbSerial.SelectedIndex!=-1){
                    //sPort.PortName = cbSerial.Text;
                    sPort.BaudRate = 19200;
                    sPort.DataBits = 8;
                    sPort.StopBits = StopBits.One;
                    sPort.Parity= Parity.None;
                    sPort.Open();
                    timer = new System.Timers.Timer(80); // 每隔80毫秒（1秒）发送一次数据
                    timer.Elapsed += OnTimedEvent;
                    timer.AutoReset = true; // 设置为true以循环触发事件
                    timer.Enabled = true; // 启动定时器
                    timerSet = true;
                                // 禁用除了button1之外的所有控件
                    foreach (var ctrl in GBx[1].Controls)
                    {
                        if(ctrl is NumericUpDown)
                            ((NumericUpDown)ctrl).Enabled = false;
                        if(ctrl is ComboBox)
                            ((ComboBox)ctrl).Enabled = false;
                    }
                }
            }else{
                bt.Text = "点击更新参数";
                bt.BackColor = Color.LightBlue;
                sPort.Close();
                timer.Enabled = false;
                timer.Dispose();
                foreach (var ctrl in GBx[1].Controls)
                {
                    if(ctrl is NumericUpDown)
                        ((NumericUpDown)ctrl).Enabled = true;
                    if(ctrl is ComboBox)
                        ((ComboBox)ctrl).Enabled = true;
                }
            }
        }
        /******************************************************
         * 改变串口comboBox中的数据
         * 
         * 
        ******************************************************/
        private void EventComComboBoxChange(object sender,EventArgs e)
        {
            var bt = (ComboBox)sender;
            if(bt.SelectedIndex<comNum.Count){
                sPort.Close();
                sPort.PortName = comNum[bt.SelectedIndex];
            }
            //cbSerial.Items.Clear();
            //string[] ports = SerialPort.GetPortNames();
            //comNum.Clear();
            //for(int i=0;i<ports.Length;i++){
            //    comNum.Add(ports[i]);
            //    string description = GetSerialPortDescription(ports[i]);
            //    cbSerial.Items.Add(ports[i]+" #"+description);
            //    cbSerial.SelectedIndexChanged += new System.EventHandler(this.EventComComboBoxChange);
            //}
            //cbSerial.SelectedIndex = cbSerial.Items.Count>0? 0:-1;
            //if(cbSerial.SelectedIndex!=-1)
            //sPort.PortName = comNum[cbSerial.SelectedIndex];
        }
        /******************************************************
         * 按键切换下载程序事件
         * 
         * 
        ******************************************************/
        private string GetSerialPortDescription(string portName)
        {
            //string query ="SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%USB%Serial%'";
            string query = "SELECT * FROM Win32_SerialPort WHERE DeviceID='" + portName + "'";
            try{
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
                {
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        return obj["Description"]?.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查询WMI时出错: {ex.Message}");
            }
            query = "SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%USB%Serial%'";
            try{
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
                {
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        return obj["Description"]?.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查询WMI时出错: {ex.Message}");
            }
            return "Description not found";
        }

        /******************************************************
         * 按键切换下载程序事件
         * 
         * 
        ******************************************************/
        private static void OnTimedEvent(Object source, ElapsedEventArgs e)
        {
            //string dataToSend = "Hello, Serial Port!"; // 要发送的数据
            //byte[] data={0x11,22,33,44,55,66};
                    //sPort.Write(data,0,data.Length);
            if(sPort.IsOpen){
                List<byte> data = new List<byte>();
                for(int i=0;i<dm.Count;i++){
                    data.Add((byte)dm[i].Value);
                }
                try
                {
                    sPort.Write(data.ToArray(),0,dm.Count);
                    Console.WriteLine($"Sent: {data}"); // 可选：在控制台输出发送的数据
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error sending data: {ex.Message}");
                }
            }
        }

        /******************************************************
         * 
         * 
         * 
        ******************************************************/
        private void PnpEntityEventArrived(object sender, EventArrivedEventArgs e)
        {
            // 处理事件，区分添加和移除事件
            //string eventType = e.NewEvent.Properties["EventType"].Value.ToString();
            //string deviceName = e.NewEvent.Properties["TargetInstance.Name"].Value.ToString();
            // 安全地获取 EventType 属性
            string eventType = null;
            try
            {
                eventType = e.NewEvent.Properties["EventType"].Value.ToString();
            }
            catch (ManagementException) { /* 属性不存在时忽略 */ }
 
            // 安全地获取 TargetInstance.Name 属性
            string deviceName = null;
            try
            {
                deviceName = e.NewEvent.Properties["TargetInstance.Name"].Value.ToString();
            }
            catch (ManagementException) { /* 属性不存在时忽略 */ }
            if (eventType == "1") // 1 表示添加事件
            {
                Console.WriteLine($"Device added: {deviceName}");
                if(timerSet==true){
                    string description = GetSerialPortDescription(deviceName);
                    cbSerial.Items.Add(deviceName+" #"+description);
                }
            }
            else if (eventType == "2") // 2 表示移除事件
            {
                Console.WriteLine($"Device removed: {deviceName}");
                if(timerSet==true){
                    string description = GetSerialPortDescription(deviceName);
                    cbSerial.Items.Remove(deviceName+" #"+description);
                }
            }
            UpdateComboBox();
        }
        private void UpdateComboBox()
        {
            if (cbSerial.InvokeRequired)
            {
                cbSerial.Invoke(new Action(UpdateComboBox));
            }
            else
            {
                cbSerial.Items.Clear();
                string[] ports = SerialPort.GetPortNames();
                comNum.Clear();
                for(int i=0;i<ports.Length;i++){
                    comNum.Add(ports[i]);
                    string description = GetSerialPortDescription(ports[i]);
                    cbSerial.Items.Add(ports[i]+" #"+description);
                    cbSerial.SelectedIndexChanged += new System.EventHandler(this.EventComComboBoxChange);
                }
                cbSerial.SelectedIndex = cbSerial.Items.Count>0? 0:-1;
                if(cbSerial.SelectedIndex!=-1)
                sPort.PortName = comNum[cbSerial.SelectedIndex];
            }
        }
    }
}
